<?php

namespace IDock\IDock;

use Exception;
use IDock\Http\Response;
use IDock\Visitor\EPolicyDownloadVisitor;
use IDock\Visitor\PolicyInfoVisitor;
use IDock\Visitor\PolicyPaymentVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\ProposalRecallVisitor;
use IDock\Visitor\ProposalStatusVisitor;
use IDock\Visitor\RenewalInquiryVisitor;
use IDock\Visitor\UnderwritingRecallVisitor;
use IDock\Visitor\UploadFileVisitor;
use IDock\Visitor\ValidateCarVisitor;
use IDock\Visitor\VehicleActualValueVisitor;
use IDock\Visitor\VehicleModelVisitor;

class IDock
{
    use IDockNonCar;

    private $IDockBean = [];

    public function setBean($shortName, $config)
    {
        $config['IDockSha'] = sha1(implode('', $config));

        if (!key_exists($shortName, $this->IDockBean)) {
            $bean = 'IDock\\Insurance\\' . $shortName . '\\' . $shortName . 'Construct';

            if (!class_exists($bean)) {
                throw new Exception('not found ' . $bean);
            }

            $bean = new $bean($config);

            $this->IDockBean[$shortName] = $bean;
        } else {
            $orgConfig = $this->IDockBean[$shortName]->getConfig();

            if ($orgConfig['IDockSha'] != $config['IDockSha']) {
                $bean = 'IDock\\Insurance\\' . $shortName . '\\' . $shortName . 'Construct';
                $this->IDockBean[$shortName] = new $bean($config);
            }
        }
    }

    /**
     * @param $shortName
     * @return mixed
     * @throws Exception
     */
    public function getBean($shortName): IDockInterface
    {
        $bean = $this->IDockBean[$shortName];
        if (!$bean) {
            throw new Exception('bean not set ' . $shortName);
        }
        return $bean;
    }

    /**
     * @param $shortName
     * @return bool
     */
    public function hasBean($shortName): bool
    {
        return key_exists($shortName, $this->IDockBean);
    }

    /**
     * @return array
     */
    public function getBeanList(): array
    {
        return array_keys($this->IDockBean);
    }

    /**
     * 续保查询
     * @param $shortName
     * @param RenewalInquiryVisitor $renewalInquiryVisitor
     * @return Response
     * @throws Exception
     */
    public function renewalInquiry($shortName, RenewalInquiryVisitor $renewalInquiryVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->renewalInquiry($renewalInquiryVisitor);
    }

    /**
     * 车型查询
     * @param $shortName
     * @param VehicleModelVisitor $vehicleModelVisitor
     * @return Response
     * @throws Exception
     */
    public function vehicleModel($shortName, VehicleModelVisitor $vehicleModelVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->vehicleModel($vehicleModelVisitor);
    }

    /**
     * 车辆实际价格
     * @param $shortName
     * @param VehicleActualValueVisitor $vehicleActualValueVisitor
     * @return Response
     * @throws Exception
     */
    public function vehicleActualValue($shortName, VehicleActualValueVisitor $vehicleActualValueVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->vehicleActualValue($vehicleActualValueVisitor);
    }

    /**
     * 询价前置
     * @param $shortName
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response
     * @throws Exception
     */
    public function preInquiry($shortName, PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->preInquiry($premiumInquiryVisitor);
    }

    /**
     * 保费计算
     * @param $shortName
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response
     * @throws Exception
     */
    public function premiumInquiry($shortName, PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->premiumInquiry($premiumInquiryVisitor);
    }

    /**
     * 核保
     * @param $shortName
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response
     * @throws Exception
     */
    public function underwriting($shortName, PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->underwriting($premiumInquiryVisitor);
    }

    /**
     * 验车
     * @param $shortName
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response
     * @throws Exception
     */
    public function validateCar($shortName, PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->validateCar($premiumInquiryVisitor);
    }

    /**
     * 支付
     * @param $shortName
     * @param PolicyPaymentVisitor $paymentVisitor
     * @return Response
     * @throws Exception
     */
    public function policyPayment($shortName, PolicyPaymentVisitor $paymentVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->policyPayment($paymentVisitor);
    }

    /**
     * 文件上传
     * @param $shortName
     * @param UploadFileVisitor $uploadFileVisitor
     * @return Response
     * @throws Exception
     */
    public function uploadFile($shortName, UploadFileVisitor $uploadFileVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->uploadFile($uploadFileVisitor);
    }

    /**
     * 投保单状态查询
     * @param $shortName
     * @param ProposalStatusVisitor $proposalStatusVisitor
     * @return Response
     * @throws Exception
     */
    public function proposalStatus($shortName, ProposalStatusVisitor $proposalStatusVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->proposalStatus($proposalStatusVisitor);
    }

    /**
     * 核保撤回
     * @param $shortName
     * @param ProposalRecallVisitor $revokeVisitor
     * @return Response
     * @throws Exception
     */
    public function proposalRecall($shortName, ProposalRecallVisitor $revokeVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->proposalRecall($revokeVisitor);
    }

    /**
     * 人工核保撤回
     * @param $shortName
     * @param UnderwritingRecallVisitor $recallVisitor
     * @return Response
     * @throws Exception
     */
    public function underwritingRecall($shortName, UnderwritingRecallVisitor $recallVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->underwritingRecall($recallVisitor);
    }

    /**
     * 电子保单下载
     * @param $shortName
     * @param EPolicyDownloadVisitor $EPolicyDownloadVisitor
     * @return Response
     * @throws Exception
     */
    public function EPolicyDownload($shortName, EPolicyDownloadVisitor $EPolicyDownloadVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->EPolicyDownload($EPolicyDownloadVisitor);
    }

    /**
     * 保单详情
     * @param $shortName
     * @param PolicyInfoVisitor $policyInfoVisitor
     * @return Response
     * @throws Exception
     */
    public function policyInfo($shortName, PolicyInfoVisitor $policyInfoVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->PolicyInfo($policyInfoVisitor);
    }

    /**
     * 验车码
     * @param $shortName
     * @param ValidateCarVisitor $validateCarVisitor
     * @return Response
     * @throws Exception
     */
    public function validateCarCode($shortName, ValidateCarVisitor $validateCarVisitor): Response
    {
        $insurance = $this->getBean($shortName);

        return $insurance->validateCarCode($validateCarVisitor);
    }
}
